package com.danicsoft.daide.command;

import com.danicsoft.daide.token.TokenGroup;
import com.danicsoft.daide.token.TokenMap.Commands;

/**
 * Implements the TME command. From Eric Wald's <a
 * href="http://pydip.brainshell.org/docs/syntax.html">protocol specification</a>,
 * v0.14:
 * <h4><a name="TME">server_message = TME</a> (seconds)</h4>
 * <p>
 * This message is sent by the server, in games where there is a time limit for
 * the turn. It indicates the number of seconds until the next deadline. It is
 * sent immediately after each turn has processed (that is, after the <b>ORD</b>,
 * <b>SCO</b> (where appropriate), and <b>NOW</b> messages).
 * </p>
 * <p>
 * In addition, the client can request <b>TME</b> to be sent at other times. To
 * do this, the client sends <b>TME (seconds)</b> to the server. The server
 * responds with <b>YES (TME (seconds))</b> to confirm this, or <b>REJ (TME
 * (seconds))</b> if <b>seconds</b> is negative, or is longer than the length
 * of the longest deadline, or if there are no deadlines. The server will then
 * send <b>TME (seconds)</b> to the client, <b>seconds</b> seconds before the
 * deadline, every turn.
 * </p>
 * <p>
 * The client can cancel such requests with <b>NOT (TME (seconds))</b> for a
 * specific request, or <b>NOT (TME)</b> for all requests. The server will
 * respond with <b>YES (NOT (...))</b> if the request was cancelled, or <b>REJ
 * (NOT (...))</b> if the specified request was not found or if the server
 * cannot cancel time requests.
 * </p>
 * <p>
 * Also, the client can send the message <b>TME</b> with no parameters. The
 * server will respond with <b>TME (seconds)</b> where <b>seconds</b> is the
 * time to the next deadline, or <b>REJ (TME)</b> if there are no deadlines.
 * </p>
 * <p>
 * The client should not acknowledge the <b>TME</b> message from the server.
 * </p>
 * 
 * @author Daniel Yule (daniel.yule@gmail.com)
 * @version 1.0
 */
public class TimeCommand extends QueryableCommand {

	/**
	 * The amount of time left until the deadline expires.
	 */
	private int timeLeft;

	/**
	 * Consutrct a new <code>TimeCommand</code> from the tokens given.
	 * 
	 * @param tokens
	 *        The tokens to construct this TimeCommand from. They should consist
	 *        of a single group containing an integer representing the time
	 *        left.
	 * @throws ParseException
	 *         If there was a problem reading from the tokens.
	 */
	public TimeCommand(TokenGroup tokens) throws ParseException {
		super(tokens);
	}

	/**
	 * Construct a new <code>TimeCommand</code> for querying the server about
	 * the time remaining until the next deadline.
	 */
	public TimeCommand() {}

	/**
	 * Consutrct a new <code>TimeCommand</code> with the given time limit
	 * 
	 * @param timeLimit
	 *        An integer representing the amount of time left on the deadline.
	 */
	public TimeCommand(int timeLimit) {
		super(false);
		timeLeft = timeLimit;
	}

	@Override
	protected void doNonQueryIO(TokenIO tokenIO, TokenGroup tokens) throws ParseException {
		timeLeft = tokenIO.doInteger(tokens, timeLeft);

	}

	@Override
	public byte getType() {
		return Commands.TME;
	}

	@Override
	public String toString() {
		return isQuery() ? "Querying the server for time remaining." : "Time remaining: " + timeLeft;
	}

	/**
	 * Gets the amount of time left before the deadline expires.
	 * 
	 * @return The amount of time before the deadline expires.
	 */
	public int getTimeLeft() {
		return timeLeft;
	}

}
